package images;

import game.Data;
import game.Data.BlocoInfo;
import static images.ImageManager.getImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import org.json.simple.JSONArray;
import org.json.simple.JSONValue;
import org.newdawn.slick.opengl.Texture;
import saves.BlocoSimples;

public class BlockLoader {

    private static Texture imgBlocks, imgWires;
    private static ImageInfo[][] blocks, wires, mini;

    public static final String BLOCKS_FILE = "blocks.png", WIRES_FILE = "wires.png";
    public static final int BLOCK_SIZE = 16;
    
    public static void load() throws IOException {
        BlocoInfo[] blocos = Data.getBlocos().toArray(new BlocoInfo[Data.getBlocos().size()]);
        imgBlocks = ImageManager.getTexture(BLOCKS_FILE);
        imgWires = ImageManager.getTexture(WIRES_FILE);
        
        blocks = new ImageInfo[blocos.length][];
        mini = new ImageInfo[blocos.length][];
        float pbx = imgBlocks.getWidth()/imgBlocks.getImageWidth(), pby = imgBlocks.getHeight()/imgBlocks.getImageHeight();
        int col = imgBlocks.getTextureWidth() / BLOCK_SIZE;
        for (int i = 0; i < blocos.length; i++) {
            blocks[i] = new ImageInfo[blocos[i].getImagens().length];
            mini[i] = new ImageInfo[blocos[i].getImagens().length];
            for (int j = 0; j < blocks[i].length; j++) {
                int pa = blocos[i].getImagens()[j].codigo + 1;
                blocks[i][j] = new ImageInfo(pa%col * BLOCK_SIZE, pa/col * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, 90*blocos[i].getImagens()[j].angulo, pbx, pby);
                mini[i][j] = new ImageInfo(imgBlocks.getImageWidth() - BLOCK_SIZE + (i + j)%BLOCK_SIZE, imgBlocks.getImageHeight() - BLOCK_SIZE + (i + j)/BLOCK_SIZE, 1, 1, 0, pbx, pby);
            }
        }
        
        wires = new ImageInfo[2][6];
        float pwx = imgWires.getWidth()/imgWires.getImageWidth(), pwy = imgWires.getHeight()/imgWires.getImageHeight();
        
        //read data from json file
        JSONArray el = (JSONArray) JSONValue.parse(new String(Files.readAllBytes(Paths.get(ImageManager.getPath() + "wires.json"))));
        for (int i = 0; i < wires.length; i++)
            for (int j = 0; j < wires[i].length; j++)
                wires[i][j] = getImage(el, i*wires[i].length + j, pwx, pwy);
    }
    
    public static void bindBlocks() {
        imgBlocks.bind();
    }
    
    public static void bindWires() {
        imgWires.bind();
    }
    
    public static void desenhar(BlocoSimples b, int x, int y, int s) {
        bindBlocks();
        desenharBloco(b, x, y, s);
        
        bindWires();
        desenharFios(b, x, y, s);
    }
    
    public static void desenharFios(BlocoSimples b, int x, int y, int s) {
        if (b instanceof BlocoSimples.Complexo) {
            boolean conexoes[] = ((BlocoSimples.Complexo) b).getConexoes(), ligado = ((BlocoSimples.Complexo) b).isEletrocutado();
            int tamanho = Data.getBlocoInfo(b.getCodigo()).getFiacao();
            int qtasCH = 0, qtasCV = 0;
            ImageInfo centro  = wires[tamanho - 1][ligado ? 1 : 0];
            ImageInfo centroE = wires[tamanho - 1][4 + (ligado ? 1 : 0)];
            ImageInfo haste   = wires[tamanho - 1][2 + (ligado ? 1 : 0)];
            int ln = (s - haste.getWidth()) / 2;
            int le = ln + haste.getWidth();
            int px = (tamanho == 1 ? 1 : 0), py = px;
            
            if (conexoes[0]) { //Cima
                qtasCV++;
                haste.draw(x + ln, y);
            }
            if (conexoes[1]) { //Direita
                qtasCH++;
                haste.draw(x + px + le - 1, y + ln - py, 90);
            }
            if (conexoes[2]) { //Baixo
                qtasCV++;
                haste.draw(x + ln, y + le - 1);
            }
            if (conexoes[3]) { //Esquerda
                qtasCH++;
                haste.draw(x + px, y + ln - py, 90);
            }

            if (qtasCH == 2 && qtasCV == 0) //Desenhar horizontal
                centroE.draw(x + ln, y + ln, 90);
            else if (qtasCH == 0 && qtasCV == 2) //Desenhar vertical
                centroE.draw(x + ln, y + ln);
            else if (qtasCH > 0 || qtasCV > 0) //Desenha normal
                centro.draw(x + ln, y + ln);
        }
    }
    
    public static void desenharBloco(BlocoSimples b, int x, int y, int s) {
        desenharBloco(blocks, b, x, y, s);
    }
    
    public static void desenharMini(BlocoSimples b, int x, int y, int s) {
        desenharBloco(mini, b, x, y, s);
    }
    
    private static void desenharBloco(ImageInfo[][] m, BlocoSimples b, int x, int y, int s) {
        ImageInfo img;
        int a = 0;
        if (b == null)
            img = new ImageInfo(s, s, imgBlocks.getWidth()/imgBlocks.getImageWidth(), imgBlocks.getHeight()/imgBlocks.getImageHeight());
        else
            if (b instanceof BlocoSimples.Complexo) {
                img = m[b.getCodigo()][((BlocoSimples.Complexo) b).getSubCodigo()];
                a = ((BlocoSimples.Complexo) b).getAngulo() * 90;
            } else
                img = m[b.getCodigo()][0];
        
        //Desenhar bloco
        img.draw(x, y, s, s, a);
    }
}
